//这里我们开始看有向图
//基本api就是下面那些，存储方式依旧是用邻接表

import edu.princeton.cs.algs4.Bag;
import edu.princeton.cs.algs4.Graph;
import edu.princeton.cs.algs4.In;

import java.util.NoSuchElementException;

public class Digraph {
    private Bag<Integer>[] adj;
    private int V;
    private int E;

    public Digraph(int v) {
        this.V = v;
        this.E = 0;
        adj = (Bag<Integer>[]) new Bag[V];
        for (int i = 0; i < V; i++) {
            adj[i] = new Bag<Integer>();
        }
    }

    // 从输入流中创建图
    public Digraph(In in) {
        if (in == null)
            throw new IllegalArgumentException("argument is null");
        try {
            this.V = in.readInt();
            if (V < 0)
                throw new IllegalArgumentException("number of vertices in a Graph must be non-negative");
            adj = (Bag<Integer>[]) new Bag[V];
            for (int v = 0; v < V; v++) {
                adj[v] = new Bag<Integer>();
            }
            int E = in.readInt();
            if (E < 0)
                throw new IllegalArgumentException("number of edges in a Graph must be non-negative");
            for (int i = 0; i < E; i++) {
                int v = in.readInt();
                int w = in.readInt();
                addEdge(v, w);
            }
        } catch (NoSuchElementException e) {
            throw new IllegalArgumentException("invalid input format in Graph constructor", e);
        }
    }

    // 添加 v-w 边
    public void addEdge(int v, int w) {
        adj[v].add(w);
        this.E++;
    }

    // 返回一个点的相邻点
    public Iterable<Integer> adj(int v) {
        return adj[v];
    }

    // 返回点的数量
    public int V() {
        return V;
    }

    // 返回边的数量
    public int E() {
        return E;
    }

    public String toString() {
        StringBuilder s = new StringBuilder();
        s.append(V + " vertices, " + E + " edges " + "\n");
        for (int v = 0; v < V; v++) {
            s.append(v + ": ");
            for (int w : adj[v]) {
                s.append(w + " ");
            }
            s.append("\n");
        }
        return s.toString();
    }

    public Digraph reverse() {
        Digraph reDigraph = new Digraph(V);
        reDigraph.adj = (Bag<Integer>[]) new Bag[V];
        for (int v = 0; v < V; v++) {
            reDigraph.adj[v] = new Bag<Integer>();
        }
        for (int i = 0; i < V; i++) {
            for (int w : adj[i]) {
                reDigraph.addEdge(w, i);
            }
        }
        return reDigraph;
    }

    public static void main(String[] args) throws Exception {
        In in = new In("input.txt");
        Digraph g = new Digraph(in);
        Topological_Sorting sort=new Topological_Sorting(g);
        for(int v:sort.ReversePost())
        {
           System.out.println(v+" ");
        }
    }
}
